#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@author: fu
"""

import sys
import time

import Common # common functions
import Config # configuration parameters

import Snake
import Food
import Box

import Map

def main():
    Common.pygame.init()
    screen_size = (Config.SCREEN_X, Config.SCREEN_Y)
    screen = Common.pygame.display.set_mode(screen_size)
    Common.pygame.display.set_caption('Snake')
    clock = Common.pygame.time.Clock()
    
    scores = 0
    stage = 0
    
    snake = Snake.Snake()
    isdead = False
    flag = 1 # next map
    
    while True:
        if flag:
            # initialize objects in the game
            time.sleep(.5)
            m = Map.Map()
            s = stage % 5 + 1
            m.set(s)
            
            # set food on the map
            food = []
            count = 2
            for i in range(count):
                f = Food.Food()
                f.set()
                food.append(f)
                
            # set boxes
            boxes = []
            count = s
            for i in range(count):
                box = Box.Box()
                box.set()
                boxes.append(box)
                
            if (len(boxes) != s) or (len(m.targets) != s):
                continue
            
            flag = 0
            
        for event in Common.pygame.event.get():
            if event.type == Common.pygame.QUIT:
                Common.pygame.quit()
                sys.exit()
                
            if event.type == Common.pygame.KEYDOWN:
                # press space to restart
                if event.key == Common.pygame.K_SPACE and isdead:
                    return main()
                
                # press esc to exit
                if event.key == Common.pygame.K_ESCAPE and isdead:
                    Common.pygame.quit()
                    sys.exit()
                    
                # get direction
                snake.changedirection(event.key)
                
        # load map
        image = Common.pygame.image.load('img/Maps/' + 'Map 1' + '.png')
        image = Common.pygame.transform.rotate(image, 0)
        screen.blit(image, (0, 0))
        
        if not isdead:
            # scores += 1
            snake.move()
        
        # eat food
        for i in range(len(food)):
            if food[i].rect == snake.body[0]:
                if food[i].type == 0:
                    snake.addnode()
                    snake.addcolor()
                    snake.length += 1
                else:
                    scores += 5 * snake.length
                    
                food.pop(i)
                break
        
        # move boxes
        b = Box.Box(snake.body[0].left, snake.body[0].top)
        l = []
        while b in boxes:
            l.append(boxes.index(b))
            b.move(snake.curdir)
            b.dir = snake.curdir
            
        s = 0
        for b in boxes:
            if b.rect in m.targets:
                s += 1
        if s == len(m.targets):
            flag = 1
            stage += 1
            scores += 10 * snake.length
            continue
        
        # draw objects
        p = []
        for i in range(snake.length):
            p.append((m.cells.index(snake.body[i]), snake.colors[i]))
            
        for f in food:
            p.append((m.cells.index(f.rect), f.color))
            
        for i in range(len(boxes)):
            if (boxes[i].rect.x, boxes[i].rect.y) not in m.edges:
                if i in l:
                    boxes[i].move(snake.curdir)
            else:
                isdead = True
                continue
            p.append((m.cells.index(boxes[i].rect), boxes[i].color))
            
        for f in m.flowers:
            p.append((m.cells.index(f), m.i2))
            
        for t in m.targets:
            p.append((m.cells.index(t), m.i3))
            
        p.sort(key = lambda i: i[0])
        
        for i in p:
            image = Common.modify_img(i[1])
            screen.blit(image, m.cells[i[0]])
            
        Common.show_text(screen, (50, Config.SCREEN_Y - 70), 'Scores: ' + str(scores), (223, 223, 223))
        Common.show_text(screen, (380, Config.SCREEN_Y - 70), 'Stage: ' + str(stage + 1), (223, 223, 223))
        
        isdead = isdead or snake.isdead(m.edges)
        if isdead:
            Common.show_text(screen, (100, 200), 'YOU DEAD!', (227,29,18), False, 100)
            Common.show_text(screen, (150, 260), 'press space to try again...', (0,0,22), False, 30)
            
        Common.pygame.display.update()
        
        clock.tick(5 + stage // 5)
        
if __name__ == '__main__':
    main()